package com.newly.driver.sdk.device.video.service.impl.qiniu;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.newly.driver.sdk.device.video.cloud.device.*;
import com.newly.driver.sdk.device.video.cloud.device.qiniu.*;
import com.newly.driver.sdk.device.video.constants.DeviceConstant;
import com.newly.driver.sdk.device.video.exception.NewlyDeviceException;
import com.newly.driver.sdk.device.video.service.api.qiniu.IQiNiuDevice;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Client;
import com.qiniu.http.Response;
import com.qiniu.qvs.QvsResponse;
import com.qiniu.qvs.model.PatchOperation;
import com.qiniu.util.StringMap;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author gjm guan
 * @date 2021/10/15 18:08
 * @desc 使用七牛平台对设备做实现
 */
@Slf4j
public class QiNiuDevice extends AbstractQiNiuCloud implements IQiNiuDevice {

    @Override
    public CreateDeviceResp createDevice(CreateDeviceReq createDeviceReq) {
        try {
            Assert.notNull(createDeviceReq, "创建设备数据异常");
            Assert.notBlank(createDeviceReq.getPassword(), "password不能为空");
            Assert.notBlank(createDeviceReq.getName(), "name不能为空");
        } catch (IllegalArgumentException e) {
            throw new NewlyDeviceException(e.getMessage());
        }

        // 设置数据
        QvsDevice device = new QvsDevice();
        device.setName(createDeviceReq.getName());
        device.setUsername(createDeviceReq.getUsername());
        device.setPassword(createDeviceReq.getPassword());
        device.setDesc(createDeviceReq.getRemark());
        // 设备类型
        DeviceConstant.DeviceType type = createDeviceReq.getType();
        if (type.getValue() == DeviceConstant.DeviceType.IPC.getValue()) {
            device.setType(1);
        } else if (type.getValue() == DeviceConstant.DeviceType.NVR.getValue()) {
            device.setType(2);
        }

        StringMap params = new StringMap();
        params.put("name", device.getName());
        params.put("gbId", device.getGbId());
        params.putNotNull("username", device.getUsername());
        params.putNotNull("password", device.getPassword());
        params.put("pullIfRegister", device.isPullIfRegister());
        params.put("desc", device.getDesc());
        params.put("type", device.getType());

        // 发起创建设备请求
        Response resp = null;
        try {
            String url = String.format("%s/v1/namespaces/%s/devices", this.apiServer, this.namespaceId);
            resp = QvsResponse.post(url, params, new Client(), auth());
            //resp = this.getDeviceManager().createDevice(this.namespaceId, device);
        } catch (QiniuException e) {
            throw new NewlyDeviceException("创建云设备失败：", e);
        }

        // 解析响应数据
        JSONObject jsonObject = this.parseMap(resp);
        CreateDeviceResp createDeviceResp = new CreateDeviceResp();
        if (ObjectUtil.isEmpty(jsonObject)) {
            return createDeviceResp;
        }
        createDeviceResp.setCode(0);
        createDeviceResp.setResGroupId(jsonObject.getStr("nsId"));
        createDeviceResp.setDeviceId(jsonObject.getStr("gbId"));
        createDeviceResp.setGbId(jsonObject.getStr("gbId"));
        return createDeviceResp;
    }

    @Override
    public QueryDeviceResp listDevice(QueryDeviceReq queryDeviceReq) {
        // 关键字查询
        StringBuilder keyword = new StringBuilder();
        List<String> deviceIds = queryDeviceReq.getDeviceIds();
        if (!ObjectUtil.isEmpty(deviceIds)) {
            for (String deviceId : deviceIds) {
                keyword.append(deviceId + ",");
            }
        }

        // 发起查询设备请求
        Response resp = null;
        try {
            resp = this.getDeviceManager().listDevice(this.namespaceId,
                    queryDeviceReq.getOffset(), queryDeviceReq.getLimit()
                    , keyword.toString(), null, 0);
        } catch (QiniuException e) {
            e.printStackTrace();
        }

        // 解析响应数据
        JSONObject jsonObject = this.parseMap(resp);
        QueryDeviceResp queryDeviceResp = new QueryDeviceResp();
        if (ObjectUtil.isEmpty(jsonObject)) {
            return queryDeviceResp;
        }
        JSONArray items = jsonObject.getJSONArray("items");
        if (ObjectUtil.isEmpty(items)) {
            return queryDeviceResp;
        }
        queryDeviceResp.setCode(0);
        queryDeviceResp.setTotal(items.size());
        List<QueryDeviceResp.Payload> payloads = items.stream()
                .map(item -> new QueryDeviceResp.Payload((JSONObject) item))
                .collect(Collectors.toList());
        queryDeviceResp.setPayloads(payloads);

        return queryDeviceResp;
    }

    @Override
    public QueryDeviceResp queryDevice(String deviceId) {
        try {
            Assert.notBlank(deviceId, "deviceId不能为空");
        } catch (IllegalArgumentException e) {
            throw new NewlyDeviceException(e.getMessage());
        }

        // 发起查询设备请求
        Response response = null;
        try {
            response = this.getDeviceManager().queryDevice(this.namespaceId, deviceId);
        } catch (QiniuException e) {
            e.printStackTrace();
        }

        // 解析响应数据
        JSONObject jsonObject = this.parseMap(response);
        QueryDeviceResp queryDeviceResp = new QueryDeviceResp();
        if (ObjectUtil.isEmpty(jsonObject)) {
            return queryDeviceResp;
        }
        QueryDeviceResp.Payload payload = new QueryDeviceResp.Payload(jsonObject);
        queryDeviceResp.setCode(0);
        queryDeviceResp.setTotal(1);
        queryDeviceResp.setPayloads(Arrays.asList(payload));
        return queryDeviceResp;
    }

    @Override
    public ModifyDeviceResp modifyDevice(ModifyDeviceReq modifyDeviceReq) {
        try {
            Assert.notNull(modifyDeviceReq, "修改设备数据异常");
            Assert.notNull(modifyDeviceReq.getDeviceId(), "deviceId不能为空");
            Assert.notNull(modifyDeviceReq.getDeviceName(), "deviceName不能为空");
        } catch (IllegalArgumentException e) {
            throw new NewlyDeviceException(e.getMessage());
        }

        // 设置修改数据
        List<PatchOperation> patchOperations = new ArrayList<>();
        patchOperations.add(new PatchOperation("replace", "name", modifyDeviceReq.getDeviceName()));

        if (!StrUtil.isBlank(modifyDeviceReq.getPassword())) {
            patchOperations.add(new PatchOperation("replace", "password", modifyDeviceReq.getPassword()));
        }


        // 发起修改请求
        Response resp = null;
        try {
            PatchOperation[] patchOperationArr = new PatchOperation[patchOperations.size()];
            patchOperations.toArray(patchOperationArr);
            resp = this.getDeviceManager().updateDevice(this.namespaceId, modifyDeviceReq.getDeviceId(), patchOperationArr);
        } catch (QiniuException e) {
            throw new NewlyDeviceException("修改云设备失败", e);
        }

        // 解析响应数据
        JSONObject jsonObject = this.parseMap(resp);
        ModifyDeviceResp modifyDeviceResp = new ModifyDeviceResp();
        if (!ObjectUtil.isEmpty(jsonObject)) {
            modifyDeviceResp.setCode(0);
        } else {
            modifyDeviceResp.setCode(1);
        }
        return modifyDeviceResp;
    }

    @Override
    public RemoveDeviceResp removeDevice(RemoveDeviceReq removeDeviceReq) {
        try {
            Assert.notNull(removeDeviceReq, "删除设备数据异常");
            Assert.notBlank(removeDeviceReq.getDeviceId(), "deviceId不能为空");
        } catch (IllegalArgumentException e) {
            throw new NewlyDeviceException(e.getMessage());
        }

        // 发起删除设备请求
        Response resp = null;
        try {
            resp = this.getDeviceManager().deleteDevice(namespaceId, removeDeviceReq.getDeviceId());
        } catch (QiniuException e) {
            throw new NewlyDeviceException("删除云设备失败");
        }

        // 解析响应数据
        RemoveDeviceResp removeDeviceResp = new RemoveDeviceResp();
        JSONObject jsonObject = this.parseMap(resp);
        Integer code = jsonObject.getInt("code");
        if (!ObjectUtil.isEmpty(code) && code.equals(QiNiuRequestState.OK.getKey())) {
            removeDeviceResp.setCode(0);
        } else {
            removeDeviceResp.setCode(1);
        }
        return removeDeviceResp;
    }

    @Override
    public DeviceConstant.DeviceState queryDeviceState(String deviceId) {
        return super.queryDeviceState(deviceId);
    }

    @Override
    public DeviceConstant.DeviceType queryDeviceType(String deviceId) {
        return super.queryDeviceType(deviceId);
    }

    ///////////////////////////// 七牛独有
    @Override
    public QNCreateDeviceResp qnCreateDevice(QNCreateDeviceReq qnCreateDeviceReq) {
        return null;
    }

    @Override
    public QNRemoveDeviceReq qnRemoveDevice(QNRemoveDeviceResp qnRemoveDeviceResp) {
        return null;
    }

    @Override
    public QNQueryDeviceResp qnListDevice(QNQueryDeviceReq queryDeviceReq) {
        return null;
    }

    @Override
    public QNQueryDeviceResp qnQueryDevice(String gbId) {
        return null;
    }

    @Override
    public QNModifyDeviceResp qnModifyDevice(QNModifyDeviceReq qnModifyDeviceReq) {
        return null;
    }

    @Override
    public QNQueryChannelResp qnListChannel(QNQueryChannelReq QNQueryChannelReq) {
        return null;
    }

    @Override
    public JSONObject qnStartDeviceStream(String namespaceId, String gbId, List<String> channels) {
        return null;
    }

    @Override
    public JSONObject qnStopDeviceStream(String namespaceId, String gbId, List<String> channels) {
        return null;
    }
}
